﻿#include<iostream>

using namespace std;

//class Student
//{
//public:
//	// 进⼊校园/图书馆/实验室刷⼆维码等⾝份认证
//	void identity()
//	{
//		// ...
//	}
//
//	// 学习
//	void study()
//	{
//		// ...
//	}
//protected:
//	string _name = "peter"; // 姓名
//	string _address; // 地址
//	string _tel; // 电话
//	int _age = 18; // 年龄
//
//	int _stuid; // 学号
//};
//
//class Teacher
//{
//public:
//	// 进⼊校园/图书馆/实验室刷⼆维码等⾝份认证
//	void identity()
//	{
//		// ...
//	}
//
//	// 授课
//	void teaching()
//	{
//		//...
//	}
//protected:
//	string _name = "张三"; // 姓名
//	int _age = 18; // 年龄
//	string _address; // 地址
//	string _tel; // 电话
//
//	string _title; // 职称
//};
//
//int main()
//{
//	return 0;
//}
//
//class Person
//{
//public:
//	// 进⼊校园/图书馆/实验室刷⼆维码等⾝份认证
//	void identity()
//	{
//		cout << "void identity()" << _name << endl;
//	}
//protected: string _name = "张三"; // 姓名
//		 string _address; // 地址
//		 string _tel; // 电话
//		 int _age = 18; // 年龄
//};
//
//
//class Student : public Person
//{
//public:
//	// 学习
//	void study()
//	{
//		// ...
//	}
//
//protected:
//	int _stuid; // 学号
//};
//
//class Teacher : public Person
//{
//public:
//	// 授课
//	void teaching()
//	{
//		//...
//	}
//protected:
//	string title; // 职称
//};
//class Person
//{
//protected:
//	string _name; // 姓名
//	string _sex; // 性别
//	int _age; // 年龄
//};
//class Student : public Person
//{
//public:
//	int _No; // 学号
//};
//int main()
//{
//	Student sobj;
//	// 1.派⽣类对象可以赋值给基类的指针/引⽤
//	Person* pp = &sobj;
//	Person& rp = sobj;
//	// ⽣类对象可以赋值给基类的对象是通过调⽤后⾯会讲解的基类的拷⻉构造完成的
//	Person pobj = sobj;
//	//2.基类对象不能赋值给派⽣类对象，这⾥会编译报错
//	sobj = pobj;
//	return 0;
//}
//
//// Student的_num和Person的_num构成隐藏关系，可以看出这样代码虽然能跑，但是⾮常容易混淆
//class Person
//{
//protected:
//	string _name = "⼩李⼦"; // 姓名
//	int _num = 111; // ⾝份证号
//};
//
//class Student : public Person
//{
//public:
//	void Print()
//	{
//		cout << " 姓名:" << _name << endl;
//		cout << " ⾝份证号:" << Person::_num << endl;
//		cout << " 学号:" << _num << endl;
//	}
//protected:
//	int _num = 999; // 学号
//};
//
//int main()
//{
//	Student s1;
//	s1.Print();
//
//	return 0;
//};
//
//#include <iostream>
//using namespace std;
//
//class Person {
//public:
//    Person(const char* name = "peter") : _name(name) {
//        cout << "Person()" << endl;
//    }
//
//    Person(const Person& p) : _name(p._name) {
//        cout << "Person(const Person& p)" << endl;
//    }
//
//    Person& operator=(const Person& p) {
//        cout << "Person operator=(const Person& p)" << endl;
//        if (this != &p)
//            _name = p._name;
//        return *this;
//    }
//
//    ~Person() {
//        cout << "~Person()" << endl;
//    }
//
//protected:
//    string _name;
//};
//
//class Student : public Person {
//public:
//    Student(const char* name, int num) : Person(name), _num(num) {
//        cout << "Student()" << endl;
//    }
//
//    Student(const Student& s) : Person(s), _num(s._num) {
//        cout << "Student(const Student& s)" << endl;
//    }
//
//    Student& operator=(const Student& s) {
//        cout << "Student& operator= (const Student& s)" << endl;
//        if (this != &s) {
//            Person::operator=(s);
//            _num = s._num;
//        }
//        return *this;
//    }
//
//    ~Student() {
//        cout << "~Student()" << endl;
//    }
//
//protected:
//    int _num;
//};
//
//int main() {
//    Student s1("jack", 18);
//    Student s2(s1);
//    Student s3("rose", 17);
//    s1 = s3;
//    return 0;
//}
////C++11方法
//class Base final {
//public:
//    void func5() { cout << "Base::func5" << endl; }
//protected:
//    int a = 1;
//};
////C++98的方法
//class Derive : public Base {
//    void func4() { cout << "Derive::func4" << endl; }
//protected:
//    int b = 2;
//};
//
//int main() {
//    Base b;
//    Derive d;
//    return 0;
//}
class Person
{
public:
	string _name; // 姓名
	/*int _tel;
	int _age;
	string _gender;
	string _address;*/
	// ...
};

// 使⽤虚继承Person类
class Student : virtual public Person
{
protected:
	int _num; //学号
};

// 使⽤虚继承Person类
class Teacher : virtual public Person
{
protected:
	int _id; // 职⼯编号
};

// 教授助理
class Assistant : public Student, public Teacher
{
protected:
	string _majorCourse; // 主修课程
};

int main()
{
	// 使⽤虚继承，可以解决数据冗余和⼆义性
	Assistant a;
	a._name = "peter";

	return 0;
}
